angular.module('angular-rails-seo', [])

  .run(["$seo", function($seo) {
      return $seo.setRoutes(<%= Rails.configuration.seo.to_json %>);
  }])

  .factory("$seo", ["$location", "$rootScope", function($location, $rootScope) {
    var $seo, paths;

    return $seo = (function() {
      function $seo() {}

      // Applies the passed SEO hash to the current page
      $seo.applyData = function(data) {
        if (!data.exclude && data.title != null) {
          $seo.setTitle(data.title);
        }
      };

      // Returns the default SEO entry
      $seo.getDefault = function() {
        return paths["default"];
      };

      // Return an object containing all routing information
      $seo.getRoutes = function() {
        return paths;
      };

      // Finds the matching SEO entry for the current path, or returns the default if none is found
      $seo.match = function(path) {
        var pathKeys = Object.keys(paths);
        var key, i;

        if (path == null) {
          return $seo.getDefault();
        }

        for (var i = 0; i < pathKeys.length; i++) {
          key = pathKeys[i];

          if (paths[key].regex.test(path)) {
            return paths[key];
          }
        }

        return $seo.getDefault();
      };

      // If we found a matching path entry apply it, otherwise use the default
      $seo.refresh = function() {
        var path = $location.path();
        var data = $seo.match(path);

        if (data != null) {
          $seo.applyData(data);
        } else {
          $seo.applyData($seo.getDefault());
        }
      }

      // Assigns the routes as defined in seo.json
      $seo.setRoutes = function(data) {
        paths = data;

        var key;
        var pathKeys = Object.keys(paths);

        for (var i = 0; i < pathKeys.length; i++) {
          key = pathKeys[i];
          paths[key].regex = new RegExp(paths[key].regex);
        }

        $rootScope.$on('$locationChangeSuccess', function(e, next, current) {
          $seo.refresh();
        });
      };

      // Sets the page title, and provides a handle to it on the scope so that
      // the page name can be inserted into views
      $seo.setTitle = function(title) {
        $rootScope.pageTitle = title;
      };

      return $seo;

    })();
  }]);
